package org.zoomdev.zoom.common.caster;

import org.zoomdev.zoom.common.utils.DateTimeUtils;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;

class LocalDates {
    static class String2LocalDate implements ValueCaster {
        @Override
        public Object to(Object src) {
            try {
                return LocalDate.parse((String) src, DateTimeUtils.DATE_FORMATTER);
            } catch (Exception e) {
                throw new CasterException("Failed to parse string to LocalDate: " + src, e);
            }
        }
    }

    static class LocalDate2String implements ValueCaster {
        @Override
        public Object to(Object src) {
            try {
                return ((LocalDate) src).format(DateTimeUtils.DATE_FORMATTER);
            } catch (Exception e) {
                throw new CasterException("Failed to format LocalDate to string: " + src, e);
            }
        }
    }

    static class String2LocalTime implements ValueCaster {
        @Override
        public Object to(Object src) {
            try {
                return LocalTime.parse((String) src, DateTimeUtils.TIME_FORMATTER);
            } catch (Exception e) {
                throw new CasterException("Failed to parse string to LocalTime: " + src, e);
            }
        }
    }

    static class LocalTime2String implements ValueCaster {
        @Override
        public Object to(Object src) {
            try {
                return ((LocalTime) src).format(DateTimeUtils.TIME_FORMATTER);
            } catch (Exception e) {
                throw new CasterException("Failed to format LocalTime to string: " + src, e);
            }
        }
    }

    static class String2LocalDateTime implements ValueCaster {
        @Override
        public Object to(Object src) {
            try {
                return LocalDateTime.parse((String) src, DateTimeUtils.DATE_TIME_FORMATTER);
            } catch (Exception e) {
                throw new CasterException("Failed to parse string to LocalDateTime: " + src, e);
            }
        }
    }

    static class LocalDateTime2String implements ValueCaster {
        @Override
        public Object to(Object src) {
            try {
                return ((LocalDateTime) src).format(DateTimeUtils.DATE_TIME_FORMATTER);
            } catch (Exception e) {
                throw new CasterException("Failed to format LocalDateTime to string: " + src, e);
            }
        }
    }

    static class LocalDateTime2Timestamp implements ValueCaster {
        @Override
        public Object to(Object src) {
            try {
                return Timestamp.valueOf((LocalDateTime) src);
            } catch (Exception e) {
                throw new CasterException("Failed to convert LocalDateTime to Timestamp: " + src, e);
            }
        }
    }

    static class Timestamp2LocalDateTime implements ValueCaster {
        @Override
        public Object to(Object src) {
            try {
                return ((Timestamp) src).toLocalDateTime();
            } catch (Exception e) {
                throw new CasterException("Failed to convert Timestamp to LocalDateTime: " + src, e);
            }
        }
    }

    public static class LocalDateTime2Date implements ValueCaster {
        @Override
        public Object to(Object src) {
            return DateTimeUtils.toDate((LocalDateTime) src);
        }
    }

    public static class Date2LocalDateTime implements ValueCaster {
        @Override
        public Object to(Object src) {
            return DateTimeUtils.toLocalDateTime((Date) src);
        }
    }

    public static class LocalDate2SqlDate implements ValueCaster {
        @Override
        public Object to(Object src) {
            return java.sql.Date.valueOf((LocalDate)src);
        }
    }

    public static class LocalTime2SqlTime implements ValueCaster {
        @Override
        public Object to(Object src) {
            return java.sql.Time.valueOf((LocalTime) src);
        }
    }
}
